home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-11-20 | 3.0 KB | 134 lines | [TEXT/PJMM] |
- unit FORTUNE;
-
- interface
-
- uses
- ParameterDef;
-
- procedure Main (var p: parameterRecord);
-
- implementation
-
- procedure Main (var p: parameterRecord);
- var
- rn: integer;
- count: longInt;
- s: str255;
- function GetAt (off: longInt; var where: integer; var found: boolean): OSErr;
- var
- oe: OSErr;
- len: integer;
- function MyFSRead (len: integer; buf: ptr): OSErr;
- var
- l: longInt;
- oe: OSErr;
- begin
- l := len;
- oe := FSRead(rn, l, buf);
- if oe = eofErr then
- oe := noErr;
- if (oe = noErr) and (len <> l) then
- oe := eofErr;
- MyFSRead := oe;
- end;
- begin
- len := 255;
- if len > count - off then
- len := count - off;
- {$PUSH}
- {$R-}
- s[0] := chr(len);
- {$POP}
- if len <= 0 then
- oe := -1
- else
- oe := SetFPos(rn, fsFromStart, off);
- if oe = noErr then
- oe := MyFSRead(len, @s[1]);
- if oe <> noErr then
- s := '';
- where := Pos(concat(chr(13), '#', chr(13)), s);
- found := where > 0;
- GetAt := oe;
- end;
- procedure AddStr (where: integer);
- begin
- if where > p.hlength - p.offset then
- where := p.hlength - p.offset;
- if where > 0 then begin
- BlockMove(@s[1], ptr(longInt(p.fingeroutput^) + p.offset), where);
- p.offset := p.offset + where;
- end;
- end;
- function Rand (var rnd1, rnd2: longInt; n: integer): longInt;
- var
- r2: longInt;
- begin
- r2 := BXOR(BOR(BAND(BSR(rnd1, 1), $7FFF), BSL(rnd2, 31)), BSL(rnd1, 12));
- rnd2 := BAND(rnd1, 1);
- rnd1 := BXOR(r2, BAND(BSR(r2, 20), $00000FFF));
- Rand := BAND(rnd1, $7FFFFFFF) mod n;
- end;
-
- var
- oe, ooe: OSErr;
- pos: longInt;
- found: boolean;
- where: integer;
- rnd1, rnd2: longInt;
- begin
- s := p.param^;
- if s = '' then
- s := ':Preferences:Fortune';
- oe := FSOpen(s, 0, rn);
- if oe = noErr then begin
- oe := GetEOF(rn, count);
- if oe = noErr then begin
- { Can't use Random because we have no A5 world in the daemon }
- rnd1 := TickCount;
- rnd2 := 1;
- { TickCount isn't a very good seed, and we reseed it every time we are called, so }
- { call Rand several times to produce a more visually random sequence (probably the}
- { sequence isn't very random, but it should be good enough) }
- pos := Rand(rnd1, rnd2, count);
- pos := Rand(rnd1, rnd2, count);
- pos := Rand(rnd1, rnd2, count);
- pos := Rand(rnd1, rnd2, count);
- { Asert 0<=pos<count }
- if pos > count - 3 then
- pos := count - 3;
- found := false;
- repeat
- oe := GetAt(pos, where, found);
- if oe = noErr then
- if found then begin
- pos := pos + where + 2;
- if pos >= count then
- pos := pos - count;
- end
- else begin
- pos := pos + 250;
- if pos > count then
- oe := -1;
- end;
- until found or (oe <> noErr);
- if found then begin
- found := false;
- repeat
- oe := GetAt(pos, where, found);
- if oe = noErr then begin
- if not found then
- where := 250
- else
- where := where - 1;
- AddStr(where);
- pos := pos + where;
- end;
- until found;
- end;
- end;
- ooe := FSClose(rn);
- end;
- end;
-
- end.